package feign.config;

import feign.Logger;
import feign.RequestInterceptor;
import feign.Util;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.type.TypeFactory;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.core.ResponseResult;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.core.ResponseStatus;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.core.exception.InternalServerErrorException;
import <#if isCloudModel>${cloudSysEngName}<#else>${packageName}</#if>.utils.SingletonObject;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;

/**
 * @author zrx
 */
@Slf4j
public class DefaultFeignConfiguration {

	/**
	 * 日志级别
	 * @return
	 */
	@Bean
	public Logger.Level logLevel() {
		return Logger.Level.BASIC;
	}

	/**
	 * 解析返回结果
	 * @return
	 */
	@Bean
	public Decoder feignDecoder() {
		return (response, type) -> {
			JavaType javaType = TypeFactory.defaultInstance().constructType(type);
			if (response.body() == null) {
				throw new DecodeException(response.status(), "没有返回有效的数据", response.request());
			}
			if (response.status() != HttpStatus.SC_OK) {
				throw new InternalServerErrorException("服务异常！");
			}
			String bodyStr = Util.toString(response.body().asReader(Util.UTF_8));
			ResponseResult responseResult = SingletonObject.OBJECT_MAPPER.readValue(bodyStr, ResponseResult.class);
			if (ResponseStatus.FAILED.valueEn.equals(responseResult.getStatus())) {
				throw new InternalServerErrorException("服务异常：" + responseResult.getMsg());
			}
			return SingletonObject.OBJECT_MAPPER.readValue(SingletonObject.OBJECT_MAPPER.writeValueAsString(responseResult.getData()), javaType);
		};
	}

	/**
	 * 携带请求头以用于服务之前的token鉴权
	 * @return
	 */
	@Bean
	public RequestInterceptor requestInterceptor() {
		return template -> {
			ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder
					.getRequestAttributes();
			assert attributes != null;
			HttpServletRequest request = attributes.getRequest();
			Enumeration<String> headerNames = request.getHeaderNames();
			if (headerNames != null) {
				while (headerNames.hasMoreElements()) {
					String name = headerNames.nextElement();
					String values = request.getHeader(name);
					template.header(name, values);
				}
			}
			Enumeration<String> bodyNames = request.getParameterNames();
			StringBuilder body = new StringBuilder();
			if (bodyNames != null) {
				while (bodyNames.hasMoreElements()) {
					String name = bodyNames.nextElement();
					String values = request.getParameter(name);
					body.append(name).append("=").append(values).append("&");
				}
			}
			if (body.length() != 0) {
				body.deleteCharAt(body.length() - 1);
				template.body(body.toString());
				log.info("feign interceptor body:{}", body.toString());
			}
		};
	}

}
